package com.hxrfid.common.utils;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.hxrfid.common.config.WeixinConfig;
import com.hxrfid.common.utils.redis.RedisUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 微信模板消息推送工具类
 *
 * @author lhb
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class WeixinUtil {

    private final WeixinConfig weixinConfig;

    /**
     * 获取公众号access_token
     *
     * @return access_token
     */
    public String getAccessToken() {
        try {
            // 先从缓存获取
            String accessToken = RedisUtils.getCacheObject("weixin_access_token");
            if (StrUtil.isNotBlank(accessToken)) {
                return accessToken;
            }
            // 重新获取
            String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" +
                "&appid=" + weixinConfig.getAppId() +
                "&secret=" + weixinConfig.getSecret();

            String response = HttpUtil.get(url);
            JSONObject result = JSONUtil.parseObj(response);

            Integer errcode = result.getInt("errcode", 0);
            if (errcode != 0) {
                log.error("获取access_token失败，errcode: {}, errmsg: {}", errcode, result.getStr("errmsg"));
                throw new RuntimeException(String.format("获取access_token失败，errcode: %s, errmsg: %s", errcode, result.getStr("errmsg")));
            }

            accessToken = result.getStr("access_token");
            Integer expiresIn = result.getInt("expires_in", 7200);

            // 缓存access_token，提前5分钟过期
            RedisUtils.setCacheObject("weixin_access_token", accessToken, Duration.ofSeconds(expiresIn - 300));

            return accessToken;

        } catch (Exception e) {
            log.error("获取access_token异常", e);
            throw new RuntimeException("获取access_token失败：", e);
        }
    }

    /**
     * 发货
     */
    public void send(String transactionId, String orderNo, String logisticsNo, String logisticsFirm, String productTitles, String openId) {
        try {
            // 构建请求参数
            JSONObject entries = JSONUtil.createObj()
                .putOnce("order_key", JSONUtil.createObj()
                    .putOnce("order_number_type", "1")
                    .putOnce("transaction_id", transactionId)
                    .putOnce("mchid", weixinConfig.getMerchantId())
                    .putOnce("out_trade_no", orderNo)
                )
                .putOnce("logistics_type", "1")
                .putOnce("delivery_mode", "UNIFIED_DELIVERY")
                .putOnce("shipping_list", JSONUtil.createArray().put(
                    JSONUtil.createObj()
                        .putOnce("tracking_no", logisticsNo)
                        .putOnce("express_company", logisticsFirm)
                        .putOnce("item_desc", productTitles))
                )
                // 微信API要求ISO8601格式时间字符串，使用标准ISO8601格式（带时区偏移）
                .putOnce("upload_time", ZonedDateTime.now(ZoneId.of("Asia/Shanghai"))
                    .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME))
                .putOnce("payer",
                    JSONUtil.createObj()
                        .putOnce("openid", openId)
                );

            // 转换为JSON字符串
            String jsonBody = JSONUtil.toJsonStr(entries);
            log.debug("微信发货请求参数: {}", jsonBody);

            // 发送请求，明确指定Content-Type为application/json
            String url = "https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token=" + getAccessToken();
            String post = HttpRequest.post(url)
                .header("Content-Type", "application/json;charset=UTF-8")
                .body(jsonBody)
                .execute()
                .body();

            log.debug("微信发货响应: {}", post);

            JSONObject jsonObject = JSONUtil.parseObj(post);
            Integer errcode = jsonObject.getInt("errcode", 0);
            if (errcode != 0) {
                String errmsg = jsonObject.getStr("errmsg");
                log.error("微信发货失败，请求参数: {}, 响应: {}", jsonBody, post);
                throw new RuntimeException(String.format("发货失败，errcode: %s, errmsg: %s", errcode, errmsg));
            }
            log.info("微信发货成功，订单号: {}", orderNo);
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            log.error("微信发货异常", e);
            throw new RuntimeException("发货失败：" + e.getMessage(), e);
        }
    }

}
